package com.ruoyi.web.task.factory;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.base.PageParam;
import com.ruoyi.business.goods.domain.JbCommodity;
import com.ruoyi.business.order.domain.JbOrder;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.thirdparty.chanjet.service.ThirdpartyChanjetLogService;
import com.ruoyi.web.controller.business.goods.factory.JbCommodityFactory;
import com.ruoyi.web.controller.business.order.factory.JbOrderFactory;
import com.ruoyi.web.controller.business.order.vo.JbOrderStatusEnum;
import com.ruoyi.web.controller.business.statistics.factory.JbProductRecipeFactory;
import com.ruoyi.web.controller.thirdparty.factory.ThirdpartyExtendFactory;
import com.ruoyi.web.controller.thirdparty.factory.ThirdpartyGoodsFactory;
import com.ruoyi.web.controller.thirdparty.factory.ThirdpartyOrderFactory;
import com.ruoyi.web.controller.thirdparty.vo.ThirdpartyGoodsVO;
import com.ruoyi.web.core.JoController;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 任务 第三方 工厂
 *
 * @author Jyl
 */
@Log4j2
@Component
public class TaskThirdpartyFactory extends JoController
{

    @Autowired
    private JbOrderFactory jbOrderFactory;
    @Autowired
    private JbCommodityFactory jbCommodityFactory;
    @Autowired
    private JbProductRecipeFactory jbProductRecipeFactory;
    @Autowired
    private ThirdpartyOrderFactory thirdpartyOrderFactory;
    @Autowired
    private ThirdpartyGoodsFactory thirdpartyGoodsFactory;
    @Autowired
    private ThirdpartyExtendFactory thirdpartyExtendFactory;
    @Autowired
    private ThirdpartyChanjetLogService thirdpartyChanjetLogService;

    /**
     * 更新订单信息
     */
    public void fnUpdateOrder()
    {
        /**
         * 查询发货中数据
         */
        List<JbOrder> list = jbOrderFactory.listByStatus(Arrays.stream(new StringJoiner(",")
                .add(JbOrderStatusEnum.task9.getKey())
                .add(JbOrderStatusEnum.task11.getKey())
                .toString().split(",")).toList());
        for (JbOrder jbOrder : list)
        {

            //1.根据 销货单号查询物流信息
            Map<String, JSONObject> map = new HashMap<>();
            String[] orderCode = jbOrder.getYySaleDeliveryCode().split(",");
            for (String s : orderCode)
            {
                //查询通用单据报表
                try
                {
                    map = thirdpartyOrderFactory.queryOrder(s, jbOrder.getOrderNumber());
                } catch (IOException | InterruptedException e)
                {
                    log.error("[{}]:{} && {}>>>{}", "更新订单信息", jbOrder.getOrderNumber(), s, e);
                }
            }

            //没有物流信息 跳过当前回合
            if (ObjectUtil.isEmpty(map))
            {
                continue;
            }

            //2.处理合并物流信息
            Map<String, JSONObject> wuliuMap = new HashMap<>();
            for (JSONObject jsonObject : map.values())
            {
                if (StrUtil.isNotEmpty(jsonObject.getString("SaleDeliverypubuserdefnvc5")))
                {
                    String wuliudanhao = jsonObject.getString("SaleDeliverypubuserdefnvc2");
                    String wuliufeiyong = jsonObject.getString("SaleDeliverypubuserdefnvc5");

                    JSONObject shangpinJson = new JSONObject()
                            .fluentPut("shangpinming", jsonObject.getString("inventoryName"))
                            .fluentPut("shangpinbianma", jsonObject.getString("inventoryCode"))
                            .fluentPut("shangpinshuliang", jsonObject.getString("quantity"));

                    JSONObject wuliuJson = new JSONObject()
                            .fluentPut("wuliushangpin", new JSONArray().fluentAdd(shangpinJson))
                            .fluentPut("wuliugongsi", jsonObject.getString("SaleDeliverypubuserdefnvc1"))
                            .fluentPut("wuliudanhao", wuliudanhao)
                            .fluentPut("wuliudianhua", jsonObject.getString("SaleDeliverypubuserdefnvc3"))
                            .fluentPut("wuliufeiyong", wuliufeiyong);

                    //物流单号 一致
                    if (wuliuMap.containsKey(wuliudanhao))
                    {
                        //添加物流商品组
                        wuliuMap.get(wuliudanhao).getJSONArray("wuliushangpin").add(shangpinJson);
//                        //合并物流费用
//                        //历史条 物流费
//                        String wuliufeiyongOld = wuliuMap.get(wuliudanhao).getString("wuliufeiyong");
//                        //合计物流费
//                        BigDecimal wuliufeiyongBigDecimal = new BigDecimal(wuliufeiyong)
//                                .add(new BigDecimal(wuliufeiyongOld))
//                                .setScale(2, RoundingMode.HALF_UP);
//                        //合计到历史条物流费上
//                        wuliuMap.get(wuliudanhao).fluentPut("wuliufeiyong", wuliufeiyongBigDecimal.toString());
                    } else
                    {
                        wuliuMap.put(jsonObject.getString("SaleDeliverypubuserdefnvc2"), wuliuJson);
                    }
                }
            }

            //3.更新物流信息
            JSONArray jsonArray = new JSONArray();
            jsonArray.addAll(wuliuMap.values());

            jbOrder.setYyLogisticsInformation(jsonArray);
            if (orderCode.length == jsonArray.size())
            {
                //物流信息获取完毕标识
                jbOrder.setYyLogisticsIsAll(true);
                //TODO 用户物流费用，重新计算 毛利率 提成 收益
            }

            jbOrderFactory.getService().updateById(jbOrder);
        }
    }

    /**
     * 更新外部系统编码
     */
    public void fnUpdateTnumber()
    {
        List<JbOrder> list = jbOrderFactory.findNotYySaleDeliveryIsAll();
        for (JbOrder jbOrder : list)
        {
            int yySalesOrderCount = jbOrder.getYySalesOrderCount();
            jbOrder.setYySalesOrderCount(++yySalesOrderCount);
            fnQuThirdpartyCode(jbOrder);
        }
    }

    /**
     * 更新库存成本
     */
    public void updateInventoryCost()
    {
        PageParam pageParam = new PageParam();
        Boolean b = true;
        jbProductRecipeFactory.isGoodsAll();
        for (int i = 0; b; i++)
        {
            b = false;
            pageParam.setPageNum(i + 1);
            List<JbCommodity> list = jbCommodityFactory.getService().page(pageParam.b()).getRecords();
            if (list.isEmpty())
            {
                log.info("[{}]:{}", "更新库存成本(updateInventoryCost)", "完成(complete)");
                return;
            }
            b = true;

            StringJoiner joiner = new StringJoiner(",");
            List<Long> ids = new ArrayList<>();
            Map<String, Long> commodityMap = new HashMap<>();//用友编码：商品主键
            Map<String, BigDecimal> caseQuantityMap = new HashMap<>();//用友编码：商品整件数量
            for (JbCommodity jbCommodity : list)
            {
                ids.add(jbCommodity.getId());
                joiner.add(jbCommodity.getCommodityCode());
                commodityMap.put(jbCommodity.getCommodityCode(), jbCommodity.getId());
                caseQuantityMap.put(jbCommodity.getCommodityCode(), BigDecimal.valueOf(jbCommodity.getCaseQuantity()));
            }

            try
            {
                JSONObject jsonObject = thirdpartyGoodsFactory.inventoryQuery(joiner.toString());
                JSONArray jsonArray = jsonObject.getJSONArray("body");
                for (Object o : jsonArray)
                {
                    ThirdpartyGoodsVO goodsVO = JSONObject.parseObject(o.toString(), ThirdpartyGoodsVO.class);
                    if (commodityMap.containsKey(goodsVO.getCode()))
                    {
                        BigDecimal inventoryCost = goodsVO.getAvagCost().setScale(2, RoundingMode.HALF_UP);
                        BigDecimal inventoryUnitCost = inventoryCost.divide(caseQuantityMap.get(goodsVO.getCode()), 2
                                , RoundingMode.HALF_UP);
                        jbProductRecipeFactory.updateByCommodityCode(commodityMap.get(goodsVO.getCode()),
                                inventoryCost, inventoryUnitCost);
                    } else
                    {
                        log.error("[{}]:{}>>>{}", "更新库存成本(updateInventoryCost)", "未找到商品(product not found)",
                                goodsVO.getCode());
                    }
                }
            } catch (IOException | InterruptedException e)
            {
                log.error("[{}]:{}", "更新库存成本(updateInventoryCost)", e.toString());
            }
        }
    }

    /**
     * 通知用友下单
     */
    public void sendThirdpartyPlaceAnOrder()
    {
        List<JbOrder> list = jbOrderFactory.findNullYyOrderCode();
        for (JbOrder jbOrder : list)
        {
            jbOrderFactory.fnThirdpartyOrderCreate(jbOrder);
            jbOrder.setYySalesOrderCount(0);//初始化查询次数记录
            fnQuThirdpartyCode(jbOrder);
        }
    }

    /**
     * 查询 第三方订单 并 更新业务订单
     *
     * @param jbOrder
     */
    private void fnQuThirdpartyCode(JbOrder jbOrder)
    {
        try
        {
            JSONObject rBody = thirdpartyOrderFactory.queryExecuting(jbOrder.getOrderNumber());
            if (ObjectUtil.isEmpty(rBody))
            {
                log.error("[{}]:{}>>>{}", "查询销售订单(queryExecuting)", "没有查到销售订单",
                        jbOrder.getOrderNumber());
                return;
            }
            String saleOrderCode = rBody.getString("saleOrderCode");//销售订单
            boolean saleQuantity = rBody.getBoolean("saleQuantity");//销货单是否发货完成
            String externalCode = rBody.getString("externalCode");//外部订单号
            String saleDeliveryCode = rBody.getString("saleDeliveryCode");//销货单
            Integer saleDeliveryRowCount = rBody.getInteger("saleDeliveryRowCount");//销货单应有数量
            Integer completeCount = rBody.getInteger("completeCount");//销货单已有数量

            if (StringUtils.isBlank(saleOrderCode))
            {
                log.error("[{}]:{}>>>{}", "查询销售订单(queryExecuting)", "未查询到销售订单号", jbOrder.getOrderNumber());
                return;
            }
            if (StringUtils.isBlank(externalCode))
            {
                log.error("[{}]:{}>>>{}", "查询销售订单(queryExecuting)", "未查询到外部订单号", jbOrder.getOrderNumber());
                return;
            }
            if (!StringUtils.equals(jbOrder.getOrderNumber(), externalCode))
            {
                log.error("[{}]:{}>>>{}>>>{}", "查询销售订单(queryExecuting)", "销售订单外部单号与业务单号不匹配"
                        , jbOrder.getOrderNumber()
                        , externalCode);
                return;
            }

            //销售订单编号
            jbOrder.setYySaleOrderCode(saleOrderCode);
            //销货单编号
            jbOrder.setYySaleDeliveryCode(saleDeliveryCode);
            //是否已全部获取销货单
            boolean isAll = Objects.equals(saleDeliveryRowCount, completeCount);
            //更新订单状态 防治再次创建销售订单
            String status = JbOrderStatusEnum.task8.getKey();

            if (isAll && saleQuantity)
            {//是否获取全部销货单号 && 是否销货单全部发货
                log.info("[{}]:{}>>>{}", "查询销售订单(queryExecuting)", "查询未完结", rBody);
                jbOrder.setYySaleDeliveryIsAll(isAll);

                if ("1002".equals(jbOrder.getPaymentType()))
                {//全款的情况下，创建部分销货单为发货中，销货单全部创建完毕就是已结清。
                    status = JbOrderStatusEnum.task11.getKey();
                    jbOrder.setIsBusinessEnd(true);
                } else
                {//定金情况下，创建部分销货单为发货中，销货单全部创建完毕就是已发货，款全部回完就是已结清。
                    status = JbOrderStatusEnum.task9.getKey();
                }
            }
            jbOrder.setOrderStatus(status);
            jbOrderFactory.getService().updateById(jbOrder);
            log.info("[{}]:{}>>>{}", "查询销售订单(queryExecuting)", "更新成功", jbOrder.toString());
        } catch (IOException | InterruptedException e)
        {
            log.error("[{}]:{}>>>{}", "查询销售订单(queryExecuting)", "执行异常", e);
        }
    }

}
